package edu.uta.parsers;

import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

import com.google.android.maps.MapActivity;

import edu.uta.beans.MapDataBean;
import edu.uta.ui.Caller;

/*https://github.com/ericonjava/ericonjava/blob/master/IpGeolocate/src/com/ericonjava/GeoIpTranslateTask.java
 * http://stackoverflow.com/questions/4538338/progressdialog-in-asynctask
 * 
 *  @author fall 2011 team5
*/
public class NewParser extends AsyncTask<Hashtable<String, MapDataBean>, Hashtable<String, MapDataBean>, Hashtable<String, MapDataBean>>{


	private Caller caller;
	 /** progress dialog to show user that the backup is processing. */
    private ProgressDialog dialog;

    private Context context;

    
	public NewParser(MapActivity activity, Caller caller){
		this.caller = caller;
         context = activity;
         dialog = new ProgressDialog(context);

	}

	    protected Hashtable <String, MapDataBean> doInBackground(Hashtable <String, MapDataBean> hTable) {

	        return getAQIData();
	    }



	    protected void onPostExecute(Hashtable <String, MapDataBean> hTable) {
	     
	    caller.postRequestHandler(hTable);
	    if (dialog.isShowing()) {
            dialog.dismiss();
        }

	 
	    }

	public static Hashtable<String, MapDataBean> getAQIData()
	{
		String todayUrl = "http://www.epa.gov/airnow/today/airnow_today.kml";
		String forecast ="http://www.epa.gov/airnow/today/airnow_tomorrow.kml";
		//Hashtable<String, MapDataBean> todayTable = new Hashtable<String,MapDataBean> ();

		 
		//String str;
		Hashtable<String, MapDataBean> todayTable = getAQI(todayUrl);
		//System.out.println("******MapDataBean********" + todayTable.size());
		todayTable = getAQI(todayTable,forecast);

		/*Set<String> set = todayTable.keySet();

		System.out.println("******MapDataBean********" + todayTable.size());
		Iterator<String> itr = set.iterator();
		while (itr.hasNext()) {
			str = itr.next();
			System.out.println(str + ": " + todayTable.get(str));
		}

		System.out.println();*/
		return todayTable;
	}
	
	private static Hashtable<String, MapDataBean> getAQI(
			Hashtable<String, MapDataBean> todayTable, String forecast2) {
		
		
		Document doc = null;

		URL url = null;
		MapDataBean dataBean;
		
		try
		{
			
			//using DOM parser to read kml

            url = new URL(forecast2);
            
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            
            InputStream in = url.openStream();
			
            doc = db.parse(in);
            //eliminate empty textual nodes.
           	doc.getDocumentElement ().normalize ();
		//get all list of all elements with name Placemark
			NodeList listPlacemark = doc.getElementsByTagName("Placemark");
			
			//iterate through the list of placemark		
			for(int s=0; s<listPlacemark.getLength() ; s++){
				Node AllPlacemark = listPlacemark.item(s);
				dataBean = new MapDataBean();
				if(AllPlacemark.getNodeType() == Node.ELEMENT_NODE){
					Element descriptionElement = (Element)AllPlacemark;
					NodeList descriptionList = descriptionElement.getElementsByTagName("description");
					//get description
					Element description = (Element)descriptionList.item(0);					
					NodeList desc = description.getChildNodes();					
					String html =((Node)desc.item(0)).getNodeValue().trim();
					//parse description in html format
					String info = HtmlParser.parseHtmlToString(html);
					//set value to bean
					String place = getLocation(info);
					
					dataBean.setPlace(getData(place,info));
					
					//get coordinates					
					NodeList pointList = descriptionElement.getElementsByTagName("coordinates");
					Element point = (Element)pointList.item(0);
					
					NodeList pt = point.getChildNodes();
					//split value to extract lat & lng
					String latlng[] = (pt.item(0)).getNodeValue().trim().split(",");
					dataBean.setLongitude(Double.parseDouble(latlng[0]));
					dataBean.setLatitude(Double.parseDouble(latlng[1]));
					
					//get aqi
					NodeList styleList = descriptionElement.getElementsByTagName("styleUrl");
					Element style = (Element)styleList.item(0);					
					NodeList sty = style.getChildNodes();				
					String aq = (sty.item(0)).getNodeValue().trim().substring(1);
					dataBean.setAirQuality("Tomorrow's Forecast  "+aq);
					
					if(todayTable.containsKey(place))
					{
						MapDataBean bean = todayTable.get(place);
						bean.setForecastAQI(dataBean.getAirQuality());
						bean.setForecastDesc(dataBean.getPlace());
					}
					else
					//set databean to arraylist
					todayTable.put(place, dataBean);
					
				}
			}
			
		}
		catch (SAXParseException err) 
		{
//			System.out.println ("** Parsing error" + ", line "
	//				+ err.getLineNumber () + ", uri " + err.getSystemId ());
	//		System.out.println(" " + err.getMessage ());
			
			//Log.e(err.getClass().getName(), err.getMessage(), err); 

		}
		catch (SAXException e)
		{
			Exception x = e.getException ();
			((x == null) ? e : x).printStackTrace ();
			
			//Log.e(e.getClass().getName(), e.getMessage(), e); 

		}
		catch (Throwable t)
		{
			t.printStackTrace ();
		}
		
		
		return todayTable;
	}


	private static Hashtable<String, MapDataBean> getAQI(String todayUrl2) {

		Hashtable<String, MapDataBean> hTable = new Hashtable<String,MapDataBean> ();
		Document doc = null;

		URL url = null;
		MapDataBean dataBean;
		
		try
		{
			
			//using DOM parser to read kml

            url = new URL(todayUrl2);
            
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            
            InputStream in = url.openStream();
			
            doc = db.parse(in);
            //eliminate empty textual nodes.
           	doc.getDocumentElement ().normalize ();
		//get all list of all elements with name Placemark
			NodeList listPlacemark = doc.getElementsByTagName("Placemark");
			
			//iterate through the list of placemark		
			for(int s=0; s<listPlacemark.getLength() ; s++){
				Node AllPlacemark = listPlacemark.item(s);
				dataBean = new MapDataBean();
				if(AllPlacemark.getNodeType() == Node.ELEMENT_NODE){
					Element descriptionElement = (Element)AllPlacemark;
					NodeList descriptionList = descriptionElement.getElementsByTagName("description");
					//get description
					Element description = (Element)descriptionList.item(0);					
					NodeList desc = description.getChildNodes();					
					String html =((Node)desc.item(0)).getNodeValue().trim();
					//parse description in html format
					String info = HtmlParser.parseHtmlToString(html);
					//set value to bean
					String place = getLocation(info);
					
					//String aqiData = getData(place, info);
					dataBean.setPlace(getData(place, info));
					 
					//System.out.println("Place "+ info);
					//get coordinates					
					NodeList pointList = descriptionElement.getElementsByTagName("coordinates");
					Element point = (Element)pointList.item(0);
					
					NodeList pt = point.getChildNodes();
					//split value to extract lat & lng
					String latlng[] = (pt.item(0)).getNodeValue().trim().split(",");
					dataBean.setLongitude(Double.parseDouble(latlng[0]));
					dataBean.setLatitude(Double.parseDouble(latlng[1]));
					
					//get aqi
					NodeList styleList = descriptionElement.getElementsByTagName("styleUrl");
					Element style = (Element)styleList.item(0);					
					NodeList sty = style.getChildNodes();				
					String aq = (sty.item(0)).getNodeValue().trim().substring(1);
					dataBean.setAirQuality("Today's Forecast  "+aq);
					
					//set databean to arraylist
					hTable.put(place, dataBean);
					
				}
			}
			
		}
		catch (SAXParseException err) 
		{
			/*System.out.println ("** Parsing error" + ", line "
					+ err.getLineNumber () + ", uri " + err.getSystemId ());
			System.out.println(" " + err.getMessage ());*/
			
			//Log.e(err.getClass().getName(), err.getMessage(), err); 

		}
		catch (SAXException e)
		{
			Exception x = e.getException ();
			((x == null) ? e : x).printStackTrace ();
			
			//Log.e(e.getClass().getName(), e.getMessage(), e); 

		}
		catch (Throwable t)
		{
			t.printStackTrace ();
		}
		
		return hTable;
	}


	private static String getData(String place, String info) {
		StringBuffer strbuf = new StringBuffer();
		if(info.length()>0)
		{
			String location [] = info.split(place);
			for(int i=0;i<location.length;i++)
			{
				strbuf.append(location[i]);
			}
			return strbuf.toString();
		}
		else return "";
	}


	private static String getLocation(String info) {
		// TODO Auto-generated method stub
		if(info.length()>0)
		{
		String location [] = info.split("\n");
		//System.out.println("location " +location[0]);
		return location[0];
		}
		else return "";
	}

	

	@Override
	protected Hashtable<String, MapDataBean> doInBackground(Hashtable<String, MapDataBean>... params) {
		// TODO Auto-generated method stub
		return getAQIData();
	}

	protected void onPreExecute() {
        this.dialog.setMessage("Loading AQI Data On Map");
        this.dialog.show();
    }

}
